<template>
    <h2>todoList案例</h2>
    <div class="todo-container">
        <div class="todo-wrap">
            <Header :addTodo="addTodo"/>
            <List :todos="todos" :deleteTodo="deleteTodo" :updateTodoComplete="updateTodoComplete"/>
            <Footer :todos="todos" :checkAll="checkAll" :clearComplete="clearComplete"/>
        </div>
    </div>
</template>

<!--
    vue3
1.2020年9月发布的正式版
2.vue3支持大多数vue2的特性
3.vue3设计了一套强大的组合api代理了vue2的option api,复用性更强
4.更好的支持ts
5.最主要:vue3使用Proxy和Reflect代替了vue2中Object.defineProperty()方法实现了数据的响应式
6.重写了虚拟DOM,速度更快
7.新的组件 Fragment/teleport/Suspense
8.新的脚手架工具vite
-->

<script lang="ts">
    import {
        defineComponent,
        reactive,
        toRefs,
        watch,
        onMounted
    } from 'vue';
    // 引入子组件
    import Header from './components/Header.vue'
    import List from './components/List.vue'
    import Footer from './components/Footer.vue'
    import {Todo} from './types/Todo'
    import {saveTodos, getTodos} from "@/utils/localStorageUtils";

    // 暴露出去一个定义好的组件
    export default defineComponent({
        name: 'App', // 当前组件的名字
        // 注册组件
        components: {
            Header,
            List,
            Footer
        },
        setup() {
            // todoList
            const state = reactive<{ todos: Todo[] }>({
                todos: []
            })

            onMounted(()=>{
                state.todos = getTodos()
            })

            // 添加数据的方法
            const addTodo = (todo: Todo) => {
                state.todos.unshift(todo)
            }
            // 删除数据的方法
            const deleteTodo = (index: number) => {
                state.todos.splice(index, 1)
            }

            // 父组件的数据不能让子组件直接修改
            const updateTodoComplete = (todo: Todo, complete: boolean) => {
                todo.isCompleted = complete
                console.log(todo)
            }
            const checkAll = (isCheck: boolean) => {
                state.todos.forEach(todo => {
                    todo.isCompleted = isCheck
                })
            }

            // 清理已完成
            const clearComplete = () => {
                state.todos = state.todos.filter(todo => !todo.isCompleted)
            }

            // 监视todos:如果有变化,更新到浏览器缓存
            // watch(() => state.todos, (value) => {
            //     saveTodos(value)
            // }, {deep: true})
            watch(() => state.todos, saveTodos, {deep: true})
            return {
                ...toRefs(state), // 解构,将todos变成ref对象
                addTodo,
                deleteTodo,
                updateTodoComplete,
                checkAll,
                clearComplete
            }
        }
    });
</script>

<style>
    /*app*/
    .todo-container {
        width: 600px;
        margin: 0 auto;
    }

    .todo-container .todo-wrap {
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 5px;
    }
</style>
